using Engine;
using Engine.Graphics;
using Game;
using GameEntitySystem;

namespace Game
{
    /// <summary>
    /// StyleParticle 是一个粒子系统类，用于模拟和渲染一种带有旋转、上升和淡入淡出效果的粒子特效。
    /// 同时在所有粒子结束后会绘制一个光柱效果。
    /// </summary>
    public class StyleParticle : ParticleSystem<StyleParticle.Particle>
    {
        /// <summary>
        /// 表示单个粒子的数据结构，继承自 Game.Particle。
        /// 包含粒子的生命周期、位置、运动参数和颜色等信息。
        /// </summary>
        public class Particle : Game.Particle
        {
            /// <summary>
            /// 粒子剩余的存活时间（秒）。
            /// </summary>
            public float TimeToLive;

            /// <summary>
            /// 粒子围绕旋转的中心点。
            /// </summary>
            public Vector3 Center;

            /// <summary>
            /// 粒子绕中心旋转的角速度（弧度/秒）。
            /// </summary>
            public float AngularVelocity;

            /// <summary>
            /// 粒子绕中心旋转的半径。
            /// </summary>
            public float Radius;

            /// <summary>
            /// 粒子垂直方向上的移动速度。
            /// </summary>
            public float VerticalSpeed;

            /// <summary>
            /// 粒子当前的角度（弧度）。
            /// </summary>
            public float Angle;

            /// <summary>
            /// 粒子的基础颜色。
            /// </summary>
            public Color BaseColor;

            /// <summary>
            /// 粒子初始的存活时间，用于计算淡入淡出效果。
            /// </summary>
            public float InitialTimeToLive;
        }

        /// <summary>
        /// 用于渲染基本图形的渲染器。
        /// </summary>
        public PrimitivesRenderer3D m_primitivesRenderer;

        /// <summary>
        /// 标记是否已经创建了光柱效果。
        /// </summary>
        private bool m_lightBeamCreated = false;

        /// <summary>
        /// 光柱效果已经持续的时间（秒）。
        /// </summary>
        private float m_lightBeamTime = 0f;

        /// <summary>
        /// 光柱效果的总持续时间（秒）。
        /// </summary>
        private const float LightBeamDuration = 2.0f;

        /// <summary>
        /// 粒子系统的中心位置。
        /// </summary>
        private Vector3 m_centerPosition;

        /// <summary>
        /// 构造函数，初始化粒子系统。
        /// </summary>
        /// <param name="position">粒子系统在世界中的初始位置。</param>
        public StyleParticle(Vector3 position) : base(50)
        {
            m_centerPosition = position - Vector3.UnitY * 2.0f;
            Random random = new Random();

            // 初始化所有粒子的属性
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                particle.IsActive = true;
                particle.TimeToLive = 3.0f + random.Float(0, 2.0f);
                particle.InitialTimeToLive = particle.TimeToLive;
                particle.Center = m_centerPosition;
                particle.AngularVelocity = random.Float(5.0f, 10.0f);
                particle.Radius = random.Float(0.5f, 2.0f);
                particle.VerticalSpeed = random.Float(1.0f, 3.0f);
                particle.Angle = random.Float(0, MathF.PI * 2);
                particle.BaseColor = new Color(255, 0, 0, 255);
                particle.Position = CalculatePosition(particle);
            }
        }

        /// <summary>
        /// 根据粒子的当前状态计算其世界坐标。
        /// </summary>
        /// <param name="particle">要计算位置的粒子。</param>
        /// <returns>粒子的世界坐标。</returns>
        private Vector3 CalculatePosition(Particle particle)
        {
            float x = particle.Center.X + MathF.Cos(particle.Angle) * particle.Radius;
            float y = particle.Center.Y + particle.TimeToLive * particle.VerticalSpeed;
            float z = particle.Center.Z + MathF.Sin(particle.Angle) * particle.Radius;
            return new Vector3(x, y, z);
        }

        /// <summary>
        /// 更新粒子系统的状态。
        /// 处理粒子的生命周期、位置更新和颜色变化。
        /// 当所有粒子结束后，启动光柱效果并控制其持续时间。
        /// </summary>
        /// <param name="dt">两次更新之间的时间间隔（秒）。</param>
        /// <returns>如果粒子系统和光柱效果都已完成，则返回 true；否则返回 false。</returns>
        public override bool Simulate(float dt)
        {
            dt = Math.Clamp(dt, 0f, 0.1f);
            bool hasActiveParticles = false;

            // 更新每个粒子的状态
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    hasActiveParticles = true;
                    particle.TimeToLive -= dt;

                    if (particle.TimeToLive > 0f)
                    {
                        particle.Angle += particle.AngularVelocity * dt;
                        particle.Position = CalculatePosition(particle);

                        float progress = particle.TimeToLive / particle.InitialTimeToLive;

                        // 淡入阶段
                        if (progress > 0.8f)
                        {
                            float fadeIn = (1.0f - progress) / 0.2f;
                            particle.Color = particle.BaseColor * fadeIn;
                        }
                        // 淡出阶段
                        else if (progress < 0.2f)
                        {
                            float fadeOut = progress / 0.2f;
                            particle.Color = particle.BaseColor * fadeOut;
                        }
                        // 正常显示阶段
                        else
                        {
                            particle.Color = particle.BaseColor;
                        }
                    }
                    else
                    {
                        particle.IsActive = false;
                    }
                }
            }

            // 如果所有粒子都已死亡，启动光柱效果
            if (!hasActiveParticles && !m_lightBeamCreated)
            {
                m_lightBeamCreated = true;
            }

            // 更新光柱效果的时间
            if (m_lightBeamCreated)
            {
                m_lightBeamTime += dt;
                if (m_lightBeamTime >= LightBeamDuration)
                {
                    return true;
                }
            }

            return !hasActiveParticles && m_lightBeamTime >= LightBeamDuration;
        }

        /// <summary>
        /// 渲染粒子系统和光柱效果。
        /// 使用相机信息来正确朝向和缩放粒子。
        /// </summary>
        /// <param name="camera">当前场景的相机对象。</param>
        public override void Draw(Camera camera)
        {
            if (m_primitivesRenderer == null)
            {
                m_primitivesRenderer = SubsystemParticles.PrimitivesRenderer;
            }

            // 计算面向相机的平面
            Matrix matrix = Matrix.CreateLookAt(camera.ViewPosition, camera.ViewPosition + camera.ViewDirection, Vector3.UnitY);
            Vector3 right = matrix.Right;
            Vector3 up = matrix.Up;

            // 绘制所有活跃粒子
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    float distance = Vector3.Distance(camera.ViewPosition, particle.Position);
                    float size = 0.05f * MathF.Sqrt(distance);
                    Color color = particle.Color;

                    m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                        particle.Position - right * size - up * size,
                        particle.Position + right * size - up * size,
                        particle.Position + right * size + up * size,
                        particle.Position - right * size + up * size,
                        color
                    );
                }
            }

            // 如果光柱效果已启动且未结束，则绘制光柱
            if (m_lightBeamCreated && m_lightBeamTime < LightBeamDuration)
            {
                DrawLightBeam(camera);
            }
        }

        /// <summary>
        /// 绘制从地面升起的光柱效果。
        /// </summary>
        /// <param name="camera">当前场景的相机对象。</param>
        private void DrawLightBeam(Camera camera)
        {
            float alpha = 1.0f - MathUtils.Saturate(m_lightBeamTime / LightBeamDuration);
            Color beamColor = new Color(255, 200, 100, (int)(200 * alpha));

            float beamHeight = 50.0f;
            float beamRadius = 1.5f * alpha;

            Vector3 bottomCenter = m_centerPosition;
            Vector3 topCenter = m_centerPosition + Vector3.UnitY * beamHeight;

            // 计算面向相机的水平方向
            Vector3 viewDirection = camera.ViewPosition - m_centerPosition;
            viewDirection.Y = 0;
            if (viewDirection.Length() > 0)
                viewDirection = Vector3.Normalize(viewDirection);
            else
                viewDirection = Vector3.UnitZ;

            Vector3 right = Vector3.Cross(Vector3.UnitY, viewDirection) * beamRadius;

            int segments = 8;
            for (int i = 0; i < segments; i++)
            {
                float angle1 = (float)(i * 2 * Math.PI / segments);
                float angle2 = (float)((i + 1) * 2 * Math.PI / segments);

                Vector3 offset1 = new Vector3(
                    MathF.Cos(angle1) * beamRadius,
                    0,
                    MathF.Sin(angle1) * beamRadius
                );

                Vector3 offset2 = new Vector3(
                    MathF.Cos(angle2) * beamRadius,
                    0,
                    MathF.Sin(angle2) * beamRadius
                );

                // 绘制光柱主体
                m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                    bottomCenter + offset1,
                    bottomCenter + offset2,
                    topCenter + offset2,
                    topCenter + offset1,
                    beamColor
                );

                // 绘制顶部光晕
                m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                    topCenter + offset1,
                    topCenter + offset2,
                    topCenter + offset2 + Vector3.UnitY * 0.1f,
                    topCenter + offset1 + Vector3.UnitY * 0.1f,
                    beamColor * 0.7f
                );
            }
        }
    }
    /// <summary>
    /// 表示一个龙卷风粒子系统，继承自泛型粒子系统基类。
    /// 该系统模拟龙卷风中粒子的运动轨迹、颜色变化以及生命周期管理。
    /// </summary>
    public class TornadoParticleSystem : ParticleSystem<TornadoParticleSystem.Particle>
    {
        /// <summary>
        /// 表示单个龙卷风粒子的数据结构。
        /// 包含位置、颜色、生命周期、旋转速度等属性。
        /// </summary>
        public class Particle : Game.Particle
        {
            /// <summary>
            /// 粒子剩余的存活时间（秒）。
            /// </summary>
            public float TimeToLive;

            /// <summary>
            /// 粒子初始的存活时间（秒）。
            /// </summary>
            public float InitialTimeToLive;

            /// <summary>
            /// 粒子围绕旋转的中心点。
            /// </summary>
            public Vector3 Center;

            /// <summary>
            /// 粒子绕中心旋转的角速度。
            /// </summary>
            public float AngularVelocity;

            /// <summary>
            /// 粒子的基础半径。
            /// </summary>
            public float BaseRadius;

            /// <summary>
            /// 粒子沿Y轴方向的垂直上升速度。
            /// </summary>
            public float VerticalSpeed;

            /// <summary>
            /// 粒子当前的角度（弧度）。
            /// </summary>
            public float Angle;

            /// <summary>
            /// 粒子在Y轴上的高度偏移量。
            /// </summary>
            public float HeightOffset;

            /// <summary>
            /// 控制螺旋上升紧密程度的因子。
            /// </summary>
            public float SpiralFactor;

            /// <summary>
            /// 控制粒子路径噪声扰动程度的因子。
            /// </summary>
            public float NoiseFactor;
        }

        /// <summary>
        /// 用于渲染粒子的3D图元渲染器实例。
        /// </summary>
        public PrimitivesRenderer3D m_primitivesRenderer;

        /// <summary>
        /// 龙卷风系统的中心位置。
        /// </summary>
        private Vector3 m_centerPosition;

        /// <summary>
        /// 自系统启动以来经过的时间（秒）。
        /// </summary>
        private float m_elapsedTime = 0f;

        /// <summary>
        /// 用于生成随机数的随机数生成器。
        /// </summary>
        private Random m_random;

        /// <summary>
        /// 初始化一个新的龙卷风粒子系统实例。
        /// </summary>
        /// <param name="position">龙卷风系统的中心位置。</param>
        public TornadoParticleSystem(Vector3 position) : base(800)
        {
            m_centerPosition = position;
            m_random = new Random();

            // 初始化所有粒子的初始状态
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                particle.IsActive = true;
                particle.TimeToLive = m_random.Float(4.0f, 8.0f);
                particle.InitialTimeToLive = particle.TimeToLive;
                particle.Center = m_centerPosition;
                particle.AngularVelocity = m_random.Float(-8.0f, 8.0f);
                particle.BaseRadius = m_random.Float(1.0f, 10.0f);
                particle.VerticalSpeed = m_random.Float(0.8f, 3.0f);
                particle.Angle = m_random.Float(0, MathF.PI * 2);
                particle.HeightOffset = m_random.Float(-2.0f, 2.0f);
                particle.SpiralFactor = m_random.Float(0.8f, 3.0f);
                particle.NoiseFactor = m_random.Float(0.5f, 1.5f);

                byte goldValue = (byte)m_random.Int(200, 255);
                byte red = 255;
                byte green = (byte)m_random.Int(215, 235);
                byte blue = (byte)m_random.Int(0, 50);
                particle.Color = new Color(red, green, blue, (byte)m_random.Int(30, 80));
                particle.Position = CalculatePosition(particle);
            }
        }

        /// <summary>
        /// 根据粒子的状态计算其当前位置。
        /// 模拟了粒子随时间螺旋上升并带有噪声扰动的效果。
        /// </summary>
        /// <param name="particle">要计算位置的粒子。</param>
        /// <returns>粒子的当前位置。</returns>
        private Vector3 CalculatePosition(Particle particle)
        {
            // 计算粒子生命周期进度
            float progress = 1.0f - (particle.TimeToLive / particle.InitialTimeToLive);

            // 计算漏斗形状因子，使粒子形成类似龙卷风的漏斗结构
            float funnelFactor = MathUtils.Saturate(1.0f - Math.Abs(progress - 0.3f) * 1.8f);
            float currentRadius = particle.BaseRadius * funnelFactor * (0.3f + 0.7f * progress);

            // 添加噪声扰动
            float noise = MathF.Sin(progress * 10.0f * particle.NoiseFactor) * 0.2f;
            currentRadius *= (1.0f + noise);

            // 计算粒子的Y坐标（高度）
            float y = particle.Center.Y + progress * 25.0f + particle.HeightOffset;

            // 计算粒子绕中心旋转后的X和Z坐标
            float angle = particle.Angle + progress * particle.SpiralFactor * 10.0f;
            float x = particle.Center.X + MathF.Cos(angle) * currentRadius;
            float z = particle.Center.Z + MathF.Sin(angle) * currentRadius;

            return new Vector3(x, y, z);
        }

        /// <summary>
        /// 更新粒子系统中的每个粒子状态。
        /// 控制粒子的生命周期和重新初始化已死亡粒子。
        /// </summary>
        /// <param name="dt">两次更新之间的时间间隔（秒）。</param>
        /// <returns>如果系统运行时间超过12秒则返回true，否则返回false。</returns>
        public override bool Simulate(float dt)
        {
            dt = Math.Clamp(dt, 0f, 0.1f);
            m_elapsedTime += dt;

            // 更新所有粒子状态
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    particle.TimeToLive -= dt;

                    // 如果粒子生命周期结束，则重置粒子状态
                    if (particle.TimeToLive <= 0f)
                    {
                        particle.TimeToLive = m_random.Float(4.0f, 8.0f);
                        particle.InitialTimeToLive = particle.TimeToLive;
                        particle.Angle = m_random.Float(0, MathF.PI * 2);
                        particle.BaseRadius = m_random.Float(1.0f, 10.0f);
                        particle.AngularVelocity = m_random.Float(-8.0f, 8.0f);
                        particle.HeightOffset = m_random.Float(-2.0f, 2.0f);
                        particle.SpiralFactor = m_random.Float(0.8f, 3.0f);
                        particle.NoiseFactor = m_random.Float(0.5f, 1.5f);

                        byte goldValue = (byte)m_random.Int(200, 255);
                        byte red = 255;
                        byte green = (byte)m_random.Int(215, 235);
                        byte blue = (byte)m_random.Int(0, 50);
                        particle.Color = new Color(red, green, blue, (byte)m_random.Int(30, 80));
                    }

                    particle.Position = CalculatePosition(particle);
                }
            }

            return m_elapsedTime >= 12f;
        }

        /// <summary>
        /// 绘制所有活跃的粒子到屏幕上。
        /// 使用面向摄像机的四边形进行渲染，并根据距离调整大小和透明度。
        /// </summary>
        /// <param name="camera">当前场景使用的摄像机对象。</param>
        public override void Draw(Camera camera)
        {
            if (m_primitivesRenderer == null)
            {
                m_primitivesRenderer = SubsystemParticles.PrimitivesRenderer;
            }

            // 获取摄像机的视图矩阵以确定面向摄像机的方向
            Matrix viewMatrix = Matrix.CreateLookAt(camera.ViewPosition, camera.ViewPosition + camera.ViewDirection, Vector3.UnitY);
            Vector3 right = viewMatrix.Right;
            Vector3 up = viewMatrix.Up;

            // 渲染每一个活跃粒子
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    // 根据与摄像机的距离调整粒子大小
                    float distance = Vector3.Distance(camera.ViewPosition, particle.Position);
                    float size = 0.1f + 0.2f * MathF.Sqrt(distance);

                    // 调整粒子透明度使其在生命周期中间最亮
                    float progress = 1.0f - (particle.TimeToLive / particle.InitialTimeToLive);
                    float alphaFactor = MathUtils.Saturate(1.0f - Math.Abs(progress - 0.5f) * 2.0f);
                    alphaFactor = 0.5f + 0.5f * alphaFactor;

                    Color color = particle.Color * alphaFactor;

                    // 将粒子作为面向摄像机的四边形加入渲染队列
                    m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                        particle.Position - right * size - up * size,
                        particle.Position + right * size - up * size,
                        particle.Position + right * size + up * size,
                        particle.Position - right * size + up * size,
                        color
                    );
                }
            }
        }
    }
    /// <summary>
    /// 爆炸粒子系统类，继承自泛型粒子系统基类，用于模拟爆炸效果。
    /// 包含爆炸粒子和冲击波的模拟与渲染。
    /// </summary>
    public class ExplosionParticleSystem : ParticleSystem<ExplosionParticleSystem.Particle>
    {
        /// <summary>
        /// 爆炸粒子类，继承自基础粒子类，包含爆炸粒子的特有属性。
        /// </summary>
        public class Particle : Game.Particle
        {
            /// <summary>
            /// 粒子剩余存活时间。
            /// </summary>
            public float TimeToLive;

            /// <summary>
            /// 粒子初始存活时间。
            /// </summary>
            public float InitialTimeToLive;

            /// <summary>
            /// 粒子速度。
            /// </summary>
            public Vector3 Velocity;

            /// <summary>
            /// 粒子加速度。
            /// </summary>
            public Vector3 Acceleration;

            /// <summary>
            /// 粒子当前大小。
            /// </summary>
            public float Size;

            /// <summary>
            /// 粒子初始大小。
            /// </summary>
            public float InitialSize;

            /// <summary>
            /// 粒子初始颜色。
            /// </summary>
            public Color InitialColor;
        }

        /// <summary>
        /// 原始渲染器，用于绘制粒子和冲击波。
        /// </summary>
        public PrimitivesRenderer3D m_primitivesRenderer;

        /// <summary>
        /// 爆炸中心位置。
        /// </summary>
        private Vector3 m_centerPosition;

        /// <summary>
        /// 是否已创建冲击波。
        /// </summary>
        private bool m_shockwaveCreated = false;

        /// <summary>
        /// 冲击波已存在时间。
        /// </summary>
        private float m_shockwaveTime = 0f;

        /// <summary>
        /// 冲击波持续时间（秒）。
        /// </summary>
        private const float ShockwaveDuration = 1.5f;

        /// <summary>
        /// 构造函数，初始化爆炸粒子系统。
        /// 创建两种类型的粒子：主要爆炸粒子和高速碎片粒子。
        /// </summary>
        /// <param name="position">爆炸中心位置。</param>
        public ExplosionParticleSystem(Vector3 position) : base(150)
        {
            m_centerPosition = position;
            Random random = new Random();

            // 初始化主要爆炸粒子（占总数的80%）
            for (int i = 0; i < base.Particles.Length * 0.8f; i++)
            {
                Particle particle = base.Particles[i];
                particle.IsActive = true;
                particle.TimeToLive = random.Float(0.5f, 2.0f);
                particle.InitialTimeToLive = particle.TimeToLive;

                // 随机生成速度方向和大小
                float angle1 = random.Float(0, MathF.PI * 2);
                float angle2 = random.Float(0, MathF.PI * 2);
                float speed = random.Float(5.0f, 15.0f);

                particle.Velocity = new Vector3(
                    MathF.Cos(angle1) * MathF.Sin(angle2) * speed,
                    MathF.Cos(angle2) * speed,
                    MathF.Sin(angle1) * MathF.Sin(angle2) * speed
                );

                // 设置加速度为速度的反向，模拟减速效果
                particle.Acceleration = particle.Velocity * -0.5f;
                particle.Size = random.Float(0.1f, 0.5f);
                particle.InitialSize = particle.Size;

                // 设置粒子颜色（偏向橙红色调）
                byte red = 255;
                byte green = (byte)random.Int(100, 200);
                byte blue = (byte)random.Int(0, 50);
                byte alpha = (byte)random.Int(200, 255);

                particle.Color = new Color(red, green, blue, alpha);
                particle.InitialColor = particle.Color;
                particle.Position = m_centerPosition;
            }

            // 初始化高速碎片粒子（占总数的20%）
            for (int i = (int)(base.Particles.Length * 0.8f); i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                particle.IsActive = true;
                particle.TimeToLive = random.Float(0.3f, 1.0f);
                particle.InitialTimeToLive = particle.TimeToLive;

                // 随机生成速度方向和大小（速度更快）
                float angle1 = random.Float(0, MathF.PI * 2);
                float angle2 = random.Float(0, MathF.PI * 2);
                float speed = random.Float(10.0f, 25.0f);

                particle.Velocity = new Vector3(
                    MathF.Cos(angle1) * MathF.Sin(angle2) * speed,
                    MathF.Cos(angle2) * speed,
                    MathF.Sin(angle1) * MathF.Sin(angle2) * speed
                );

                // 设置更大的减速加速度
                particle.Acceleration = particle.Velocity * -1.0f;
                particle.Size = random.Float(0.05f, 0.2f);
                particle.InitialSize = particle.Size;

                // 设置粒子颜色（偏向亮橙色）
                byte red = 255;
                byte green = (byte)random.Int(200, 255);
                byte blue = (byte)random.Int(100, 255);
                byte alpha = (byte)random.Int(200, 255);

                particle.Color = new Color(red, green, blue, alpha);
                particle.InitialColor = particle.Color;
                particle.Position = m_centerPosition;
            }
        }

        /// <summary>
        /// 模拟粒子系统状态更新。
        /// 更新每个粒子的位置、速度、颜色和大小，并处理冲击波的创建和更新。
        /// </summary>
        /// <param name="dt">两次更新之间的时间间隔（秒）。</param>
        /// <returns>如果粒子系统已完成所有模拟则返回true，否则返回false。</returns>
        public override bool Simulate(float dt)
        {
            dt = Math.Clamp(dt, 0f, 0.1f);
            bool hasActiveParticles = false;

            // 更新所有粒子状态
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    hasActiveParticles = true;
                    particle.TimeToLive -= dt;

                    if (particle.TimeToLive > 0f)
                    {
                        // 更新粒子位置和速度
                        particle.Position += particle.Velocity * dt;
                        particle.Velocity += particle.Acceleration * dt;

                        // 根据剩余时间比例更新颜色和大小
                        float progress = particle.TimeToLive / particle.InitialTimeToLive;
                        particle.Color = particle.InitialColor * progress;
                        particle.Size = particle.InitialSize * progress;
                    }
                    else
                    {
                        // 粒子生命周期结束，标记为非活跃
                        particle.IsActive = false;
                    }
                }
            }

            // 当所有粒子都结束时创建冲击波
            if (!hasActiveParticles && !m_shockwaveCreated)
            {
                m_shockwaveCreated = true;
            }

            // 更新冲击波状态
            if (m_shockwaveCreated)
            {
                m_shockwaveTime += dt;
                if (m_shockwaveTime >= ShockwaveDuration)
                {
                    return true;
                }
            }

            return !hasActiveParticles && m_shockwaveTime >= ShockwaveDuration;
        }

        /// <summary>
        /// 绘制粒子系统。
        /// 绘制所有活跃粒子和冲击波效果。
        /// </summary>
        /// <param name="camera">当前摄像机对象，用于获取视图矩阵。</param>
        public override void Draw(Camera camera)
        {
            // 初始化渲染器
            if (m_primitivesRenderer == null)
            {
                m_primitivesRenderer = SubsystemParticles.PrimitivesRenderer;
            }

            // 获取摄像机视图矩阵，用于面向摄像机的粒子绘制
            Matrix viewMatrix = Matrix.CreateLookAt(camera.ViewPosition, camera.ViewPosition + camera.ViewDirection, Vector3.UnitY);
            Vector3 right = viewMatrix.Right;
            Vector3 up = viewMatrix.Up;

            // 绘制所有活跃粒子
            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    float size = particle.Size;
                    Color color = particle.Color;

                    // 绘制面向摄像机的四边形粒子
                    m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                        particle.Position - right * size - up * size,
                        particle.Position + right * size - up * size,
                        particle.Position + right * size + up * size,
                        particle.Position - right * size + up * size,
                        color
                    );
                }
            }

            // 绘制冲击波效果
            if (m_shockwaveCreated && m_shockwaveTime < ShockwaveDuration)
            {
                DrawShockwave(camera);
            }
        }

        /// <summary>
        /// 绘制冲击波效果。
        /// 创建一个圆形扩散的视觉效果，随时间逐渐变淡和扩大。
        /// </summary>
        /// <param name="camera">当前摄像机对象，用于获取视图矩阵。</param>
        private void DrawShockwave(Camera camera)
        {
            // 计算冲击波动画进度
            float progress = m_shockwaveTime / ShockwaveDuration;
            float radius = progress * 10.0f;
            float thickness = 0.5f * (1.0f - progress);
            float alpha = 1.0f - progress;

            // 设置冲击波颜色（橙色，透明度随时间减少）
            Color shockwaveColor = new Color(255, 150, 50, (int)(100 * alpha));

            int segments = 20;
            Matrix viewMatrix = Matrix.CreateLookAt(camera.ViewPosition, camera.ViewPosition + camera.ViewDirection, Vector3.UnitY);
            Vector3 right = viewMatrix.Right * thickness;
            Vector3 up = viewMatrix.Up * thickness;

            // 绘制冲击波圆环
            for (int i = 0; i < segments; i++)
            {
                float angle1 = (float)(i * 2 * Math.PI / segments);
                float angle2 = (float)((i + 1) * 2 * Math.PI / segments);

                Vector3 offset1 = new Vector3(MathF.Cos(angle1), 0, MathF.Sin(angle1)) * radius;
                Vector3 offset2 = new Vector3(MathF.Cos(angle2), 0, MathF.Sin(angle2)) * radius;

                // 绘制两个垂直的四边形条带形成圆环效果
                m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                    m_centerPosition + offset1 - right,
                    m_centerPosition + offset2 - right,
                    m_centerPosition + offset2 + right,
                    m_centerPosition + offset1 + right,
                    shockwaveColor
                );

                m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                    m_centerPosition + offset1 - up,
                    m_centerPosition + offset2 - up,
                    m_centerPosition + offset2 + up,
                    m_centerPosition + offset1 + up,
                    shockwaveColor
                );
            }
        }
    }
    /// <summary>
    /// 闪电粒子系统类，用于模拟和渲染闪电效果。
    /// 继承自泛型粒子系统类，管理多个闪电粒子实例。
    /// </summary>
    public class ShanDianParticleSystem : ParticleSystem<ShanDianParticleSystem.Particle>
    {
        /// <summary>
        /// 表示一个闪电粒子的数据结构。
        /// 包含位置、时间、颜色、宽度等属性。
        /// </summary>
        public class Particle : Game.Particle
        {
            /// <summary>
            /// 当前粒子剩余的存活时间（秒）。
            /// </summary>
            public float TimeToLive;

            /// <summary>
            /// 粒子初始的存活时间（秒）。
            /// </summary>
            public float InitialTimeToLive;

            /// <summary>
            /// 粒子起始位置。
            /// </summary>
            public Vector3 StartPosition;

            /// <summary>
            /// 粒子结束位置。
            /// </summary>
            public Vector3 EndPosition;

            /// <summary>
            /// 粒子路径上的关键点数组。
            /// </summary>
            public Vector3[] Points;

            /// <summary>
            /// 路径中线段的数量。
            /// </summary>
            public int SegmentCount;

            /// <summary>
            /// 分支生成概率（当前未使用）。
            /// </summary>
            public float BranchProbability;

            /// <summary>
            /// 粒子渲染时的宽度。
            /// </summary>
            public float Width;

            /// <summary>
            /// 粒子的基础颜色。
            /// </summary>
            public Color BaseColor;
        }

        /// <summary>
        /// 用于渲染基本图形的渲染器。
        /// </summary>
        public PrimitivesRenderer3D m_primitivesRenderer;

        /// <summary>
        /// 闪电主路径的起始点。
        /// </summary>
        private Vector3 m_startPosition;

        /// <summary>
        /// 闪电主路径的终点。
        /// </summary>
        private Vector3 m_endPosition;

        /// <summary>
        /// 随机数生成器。
        /// </summary>
        private Random m_random;

        /// <summary>
        /// 粒子系统是否处于激活状态。
        /// </summary>
        private bool m_isActive = true;

        /// <summary>
        /// 自粒子系统启动以来经过的时间（秒）。
        /// </summary>
        private float m_elapsedTime = 0f;

        /// <summary>
        /// 闪电效果持续时间（秒）。
        /// </summary>
        private const float Duration = 0.5f;

        /// <summary>
        /// 构造函数，初始化闪电粒子系统。
        /// 创建主闪电路径并生成分支。
        /// </summary>
        /// <param name="start">闪电起始点。</param>
        /// <param name="end">闪电结束点。</param>
        public ShanDianParticleSystem(Vector3 start, Vector3 end) : base(50)
        {
            m_startPosition = start;
            m_endPosition = end;
            m_random = new Random();

            // 初始化主闪电粒子
            Particle mainParticle = base.Particles[0];
            mainParticle.IsActive = true;
            mainParticle.TimeToLive = Duration;
            mainParticle.InitialTimeToLive = Duration;
            mainParticle.StartPosition = m_startPosition;
            mainParticle.EndPosition = m_endPosition;
            mainParticle.Points = GenerateLightningPath(m_startPosition, m_endPosition, 5);
            mainParticle.SegmentCount = mainParticle.Points.Length - 1;
            mainParticle.BranchProbability = 0.0f;
            mainParticle.Width = 0.1f;
            mainParticle.BaseColor = GenerateRandomBrightColor();
            mainParticle.Color = mainParticle.BaseColor;

            // 初始化其他粒子为非激活状态
            for (int i = 1; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                particle.IsActive = false;
            }

            // 生成分支闪电
            GenerateBranches();
        }

        /// <summary>
        /// 生成一条闪电路径的关键点。
        /// 使用随机偏移模拟闪电的不规则形状。
        /// </summary>
        /// <param name="start">路径起点。</param>
        /// <param name="end">路径终点。</param>
        /// <param name="segments">路径分段数。</param>
        /// <returns>表示路径的 Vector3 数组。</returns>
        private Vector3[] GenerateLightningPath(Vector3 start, Vector3 end, int segments)
        {
            Vector3[] points = new Vector3[segments + 1];
            points[0] = start;
            points[segments] = end;

            Vector3 direction = end - start;
            float segmentLength = direction.Length() / segments;
            direction = Vector3.Normalize(direction);

            for (int i = 1; i < segments; i++)
            {
                float progress = (float)i / segments;
                Vector3 point = start + direction * segmentLength * i;

                float offsetAmount = segmentLength * 0.5f * (1.0f - Math.Abs(progress - 0.5f) * 2.0f);
                Vector3 offset = new Vector3(
                    m_random.Float(-offsetAmount, offsetAmount),
                    m_random.Float(-offsetAmount, offsetAmount),
                    m_random.Float(-offsetAmount, offsetAmount)
                );

                points[i] = point + offset;
            }

            return points;
        }

        /// <summary>
        /// 随机生成一个明亮的颜色。
        /// 用于闪电的颜色变化。
        /// </summary>
        /// <returns>生成的 Color 对象。</returns>
        private Color GenerateRandomBrightColor()
        {
            int colorType = m_random.Int(0, 5);
            switch (colorType)
            {
                case 0:
                    return new Color((byte)255, (byte)m_random.Int(50, 150), (byte)m_random.Int(50, 150), (byte)255);
                case 1:
                    return new Color((byte)m_random.Int(50, 150), (byte)255, (byte)m_random.Int(50, 150), (byte)255);
                case 2:
                    return new Color((byte)m_random.Int(50, 150), (byte)m_random.Int(50, 150), (byte)255, (byte)255);
                case 3:
                    return new Color((byte)255, (byte)255, (byte)m_random.Int(50, 150), (byte)255);
                case 4:
                    return new Color((byte)255, (byte)m_random.Int(50, 150), (byte)255, (byte)255);
                case 5:
                    return new Color((byte)m_random.Int(50, 150), (byte)255, (byte)255, (byte)255);
                default:
                    return new Color((byte)255, (byte)255, (byte)255, (byte)255);
            }
        }

        /// <summary>
        /// 生成闪电的分支路径。
        /// 在主路径上随机生成分支闪电。
        /// </summary>
        private void GenerateBranches()
        {
            int branchCount = 0;
            for (int i = 1; i < base.Particles.Length && branchCount < 15; i++)
            {
                if (m_random.Float(0f, 1f) > 0.3f) continue;

                int mainSegment = m_random.Int(0, base.Particles[0].SegmentCount - 1);
                Vector3 startPoint = base.Particles[0].Points[mainSegment];

                Vector3 direction = Vector3.Normalize(m_endPosition - m_startPosition);
                Vector3 perpendicular = Vector3.Cross(direction, Vector3.UnitY);
                if (perpendicular.Length() < 0.1f)
                    perpendicular = Vector3.Cross(direction, Vector3.UnitX);
                perpendicular = Vector3.Normalize(perpendicular);

                Vector3 branchDirection = Vector3.Transform(perpendicular, Matrix.CreateFromAxisAngle(direction, m_random.Float(0, MathF.PI * 2)));
                Vector3 endPoint = startPoint + branchDirection * m_random.Float(1.0f, 3.0f);

                Particle particle = base.Particles[i];
                particle.IsActive = true;
                particle.TimeToLive = Duration * 0.7f;
                particle.InitialTimeToLive = Duration * 0.7f;
                particle.StartPosition = startPoint;
                particle.EndPosition = endPoint;
                particle.Points = GenerateLightningPath(startPoint, endPoint, 3);
                particle.SegmentCount = particle.Points.Length - 1;
                particle.BranchProbability = 0.0f;
                particle.Width = 0.05f;
                particle.BaseColor = GenerateRandomBrightColor();
                particle.Color = particle.BaseColor * 0.7f;

                branchCount++;
            }
        }

        /// <summary>
        /// 更新粒子系统的状态。
        /// 控制粒子的生命周期和颜色变化。
        /// </summary>
        /// <param name="dt">时间增量（秒）。</param>
        /// <returns>如果粒子系统已完成则返回 true，否则返回 false。</returns>
        public override bool Simulate(float dt)
        {
            dt = Math.Clamp(dt, 0f, 0.1f);
            m_elapsedTime += dt;

            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    particle.TimeToLive -= dt;

                    if (particle.TimeToLive <= 0f)
                    {
                        particle.IsActive = false;
                    }
                    else
                    {
                        float progress = particle.TimeToLive / particle.InitialTimeToLive;
                        byte alpha = (byte)(255 * progress);

                        float hueShift = m_elapsedTime * 2.0f;
                        Color shiftedColor = ShiftHue(particle.BaseColor, hueShift);
                        particle.Color = shiftedColor * progress;

                        if (i == 0)
                            particle.Color = shiftedColor * progress;
                        else
                            particle.Color = shiftedColor * (progress * 0.7f);
                    }
                }
            }

            if (m_elapsedTime >= Duration)
                m_isActive = false;

            return !m_isActive;
        }

        /// <summary>
        /// 对颜色进行色调偏移处理。
        /// 用于实现闪电颜色的动态变化效果。
        /// </summary>
        /// <param name="originalColor">原始颜色。</param>
        /// <param name="shift">色调偏移量（弧度）。</param>
        /// <returns>偏移后的颜色。</returns>
        private Color ShiftHue(Color originalColor, float shift)
        {
            float r = originalColor.R / 255.0f;
            float g = originalColor.G / 255.0f;
            float b = originalColor.B / 255.0f;

            shift = shift % (float)(Math.PI * 2);
            float sinShift = (float)Math.Sin(shift);
            float cosShift = (float)Math.Cos(shift);

            byte newR = (byte)(MathUtils.Clamp((r + Math.Abs(sinShift) * 0.5f) * 255, 0, 255));
            byte newG = (byte)(MathUtils.Clamp((g + Math.Abs(cosShift) * 0.5f) * 255, 0, 255));
            byte newB = (byte)(MathUtils.Clamp((b + Math.Abs(sinShift + cosShift) * 0.5f) * 255, 0, 255));

            return new Color(newR, newG, newB, originalColor.A);
        }

        /// <summary>
        /// 渲染所有激活的粒子。
        /// 调用 DrawLightningSegment 方法绘制每个粒子。
        /// </summary>
        /// <param name="camera">当前摄像机对象。</param>
        public override void Draw(Camera camera)
        {
            if (m_primitivesRenderer == null)
            {
                m_primitivesRenderer = SubsystemParticles.PrimitivesRenderer;
            }

            for (int i = 0; i < base.Particles.Length; i++)
            {
                Particle particle = base.Particles[i];
                if (particle.IsActive)
                {
                    DrawLightningSegment(particle, camera);
                }
            }
        }

        /// <summary>
        /// 绘制单个闪电段。
        /// 根据摄像机视角计算面向摄像机的四边形并进行渲染。
        /// </summary>
        /// <param name="particle">要绘制的粒子。</param>
        /// <param name="camera">当前摄像机对象。</param>
        private void DrawLightningSegment(Particle particle, Camera camera)
        {
            Matrix viewMatrix = Matrix.CreateLookAt(camera.ViewPosition, camera.ViewPosition + camera.ViewDirection, Vector3.UnitY);
            Vector3 right = viewMatrix.Right;

            Color color = particle.Color;
            float width = particle.Width;

            for (int i = 0; i < particle.SegmentCount; i++)
            {
                Vector3 start = particle.Points[i];
                Vector3 end = particle.Points[i + 1];

                Vector3 direction = end - start;
                Vector3 normal = Vector3.Cross(direction, camera.ViewDirection);
                if (normal.Length() > 0.001f)
                {
                    normal = Vector3.Normalize(normal) * width;

                    m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                        start - normal,
                        start + normal,
                        end + normal,
                        end - normal,
                        color
                    );
                }
                else
                {
                    Vector3 fallbackNormal = right * width;
                    m_primitivesRenderer.FlatBatch(0, DepthStencilState.None, null, BlendState.Additive).QueueQuad(
                        start - fallbackNormal,
                        start + fallbackNormal,
                        end + fallbackNormal,
                        end - fallbackNormal,
                        color
                    );
                }
            }
        }
    }
    /// <summary>
    /// 自定义模组加载器类，继承自 ModLoader，用于处理特定方块击中生物时的粒子效果和行为。
    /// </summary>
    public class StomeModloader : ModLoader
    {
        /// <summary>
        /// 玩家组件实例。
        /// </summary>
        public ComponentPlayer player;

        /// <summary>
        /// 样式粒子组件实例。
        /// </summary>
        public StyleParticle styleParticle;

        /// <summary>
        /// 粒子子系统实例，用于管理游戏中的粒子效果。
        /// </summary>
        private SubsystemParticles m_subsystemParticles;

        /// <summary>
        /// 当前项目实例。
        /// </summary>
        public Project project;

        /// <summary>
        /// 模组初始化方法，在模组加载时注册所需的钩子函数。
        /// </summary>
        public override void __ModInitialize()
        {
            ModsManager.RegisterHook("OnMinerHit", this);
            ModsManager.RegisterHook("OnProjectLoaded", this);
        }

        /// <summary>
        /// 当项目加载完成时调用，获取粒子子系统实例。
        /// </summary>
        /// <param name="project">当前加载的项目对象。</param>
        public override void OnProjectLoaded(Project project)
        {
            m_subsystemParticles = project.FindSubsystem<SubsystemParticles>(throwOnError: true);
        }

        /// <summary>
        /// 当矿工击中目标时触发的回调方法，根据使用的方块类型触发不同的粒子效果和行为。
        /// </summary>
        /// <param name="miner">执行攻击的矿工组件。</param>
        /// <param name="componentBody">被击中的身体组件。</param>
        /// <param name="hitPoint">击中点坐标。</param>
        /// <param name="hitDirection">击中方向向量。</param>
        /// <param name="attackPower">攻击强度（可修改）。</param>
        /// <param name="playerProbability">玩家触发概率（可修改）。</param>
        /// <param name="creatureProbability">生物触发概率（可修改）。</param>
        /// <param name="Hitted">是否成功击中的输出参数。</param>
        public override void OnMinerHit(
            ComponentMiner miner,
            ComponentBody componentBody,
            Vector3 hitPoint,
            Vector3 hitDirection,
            ref float attackPower,
            ref float playerProbability,
            ref float creatureProbability,
            out bool Hitted)
        {
            Hitted = false;
            // 如果被击中实体为空则直接返回
            if (componentBody?.Entity == null) return;

            IInventory inventory = miner.Inventory;
            int activeBlockValue = miner.ActiveBlockValue;
            int blockIndex = Terrain.ExtractContents(activeBlockValue);

            var creatureComponent = componentBody.Entity.FindComponent<ComponentCreature>();
            // 如果未找到生物组件则返回
            if (creatureComponent == null) return;

            // 根据不同方块索引触发对应的效果处理逻辑
            switch (blockIndex)
            {
                case var idx when idx == BlocksManager.GetBlockIndex<StickBlock>():
                    HandleGuangZhuEffects(hitPoint, creatureComponent);
                    break;
                case var idx when idx == BlocksManager.GetBlockIndex<CoalOreBlock>():
                    HandleStomeEffects(hitPoint, creatureComponent);
                    break;
                case var idx when idx == BlocksManager.GetBlockIndex<DiamondOreBlock>():
                    HandleExplosionEffects(hitPoint, creatureComponent);
                    break;
                case var idx when idx == BlocksManager.GetBlockIndex<IronOreBlock>():
                    HandleLightningEffects(hitPoint, creatureComponent);
                    break;
            }
        }

        /// <summary>
        /// 处理“光柱”效果：添加多种粒子效果并降低生物行走速度。
        /// </summary>
        /// <param name="hitPoint">击中点位置。</param>
        /// <param name="creature">被击中的生物组件。</param>
        private void HandleGuangZhuEffects(Vector3 hitPoint, ComponentCreature creature)
        {
            m_subsystemParticles.AddParticleSystem(new FireworksParticleSystem(hitPoint, Color.Blue, FireworksBlock.Shape.SmallBurst, 0.3f, 0.5f));
            m_subsystemParticles.AddParticleSystem(new HitValueParticleSystem(hitPoint + new Vector3(0, 0.5f, 0), new Vector3(0, 0.5f, 0), Color.LightBlue, "减速"));
            m_subsystemParticles.AddParticleSystem(new StyleParticle(hitPoint));
            creature.ComponentLocomotion.WalkSpeed = 1f;
            Log.Information("已开启粒子效果");
        }

        /// <summary>
        /// 处理“龙卷风”效果：在击中点生成一个龙卷风粒子系统。
        /// </summary>
        /// <param name="hitPoint">击中点位置。</param>
        /// <param name="creature">被击中的生物组件。</param>
        private void HandleStomeEffects(Vector3 hitPoint, ComponentCreature creature)
        {
            m_subsystemParticles.AddParticleSystem(new TornadoParticleSystem(hitPoint));
            Log.Information("龙卷风");
        }

        /// <summary>
        /// 处理“爆炸”效果：在击中点生成一个爆炸粒子系统。
        /// </summary>
        /// <param name="hitPoint">击中点位置。</param>
        /// <param name="creature">被击中的生物组件。</param>
        private void HandleExplosionEffects(Vector3 hitPoint, ComponentCreature creature)
        {
            m_subsystemParticles.AddParticleSystem(new ExplosionParticleSystem(hitPoint));
            Log.Information("爆炸效果");
        }

        /// <summary>
        /// 处理“闪电”效果：从击中点向上方发射一道闪电粒子。
        /// </summary>
        /// <param name="hitPoint">击中点位置。</param>
        /// <param name="creature">被击中的生物组件。</param>
        private void HandleLightningEffects(Vector3 hitPoint, ComponentCreature creature)
        {
            Vector3 lightningTarget = hitPoint + new Vector3(0, 5, 0);
            m_subsystemParticles.AddParticleSystem(new ShanDianParticleSystem(lightningTarget, hitPoint));
            Log.Information("闪电效果");
        }
    }
}